<template>
	<div class="cms-material-container">
		<el-card shadow="hover" class="mb10" v-auth="'cms:material:list'">
			<el-form :inline="true" :model="search">
				<el-form-item>
					<el-input v-model="search.name" placeholder="请输入文件名关键字" prefix-icon="el-icon-search"></el-input>
				</el-form-item>
				<el-form-item>
					<el-button icon="el-icon-search" type="primary" @click="onTableSearch()">查询</el-button>
					<el-button icon="el-icon-refresh" @click="onResetSearch()">重置</el-button>
				</el-form-item>
			</el-form>
		</el-card>
		<el-card shadow="hover">
			<el-row>
				<el-col :span="24" class="mb15">
					<el-form :inline="true">
						<el-form-item v-auth="'cms:material:upload'">
							<el-upload ref="uploadMaterialRef" list-type="picture"
								:accept="upload.accept"
								:auto-upload="false"
								:action="upload.action"
								:headers="upload.headers"
								:name="upload.name"
								:file-list="upload.images"
								:before-upload="handleBeforeUpload"
								:on-change="handleUploadChange"
								:on-exceed="handleUploadExceed"
								:on-preview="handleUploadPreview"
								:on-success="handleUploadSuccess"
								:on-remove="handleUploadRemove">
								<el-button type="primary" icon="el-icon-upload">上传</el-button>
							</el-upload>
						</el-form-item>
						<el-form-item v-auth="'cms:material:remove'">
							<el-button type="primary" class="ml10" icon="el-icon-delete" @click="onTabelRowsDel()" :disabled="tableData.selections.length <= 0">删除</el-button>
						</el-form-item>
					</el-form>
				</el-col>
				<el-col :span="24">
					<el-breadcrumb separator="/">
						<el-breadcrumb-item v-for="(key, k) in tableData.breads" :key="k">
							<h4 v-if="0 == k">{{key}}</h4>
							<a v-else-if="(tableData.breads.length - 1) != k" @click="onTreadcrumbClick(key)">{{key}}</a>
							<span v-else>{{key}}</span>
						</el-breadcrumb-item>
					</el-breadcrumb>
				</el-col>
			</el-row>
			<el-divider />
			<div ref="tableMaterialRef" class="flex-warp" v-if="tableData.data.length > 0">
				<el-row :gutter="10" class="w100">
					<el-col :xs="12" :sm="8" :md="6" :lg="6" :xl="6" class="mb10" v-for="(v, k) in tableData.data" :key="k">
						<el-checkbox-group v-model="tableData.selections">
							<div class="flex-warp">
								<div class="flex-warp-item">
									<div class="flex-warp-item-box">
										<div class="item-img" @click="onTableItemClick(v)">
											<!-- 已知文件 -->
											<el-image v-if="icons.includes(v.suffix)" :src="`/images/filetype/${v.suffix}.png`"/>
											<!-- 图片文件 -->
											<el-image v-else-if="v.size > 0 && images.includes(v.suffix)" :src="v.url" :lazy="true" 
												:initial-index="tableData.previews.indexOf(v.url)" :preview-src-list="tableData.previews"/>
											<!-- 文件目录 -->
											<el-image v-else-if="v.size === 0 && v.key.endsWith('/')" :src="`/images/filetype/dir.png`"/>
											<!-- 未知文件 -->
											<el-image v-else :src="`/images/filetype/txt.png`"/>
										</div>
										<div class="item-copy">
											<el-button type="primary" link @click="onOpenCopyUrl(v)" icon="el-icon-copy-document"></el-button>
										</div>
										<div class="item-txt">
											<div class="item-txt-title">
												<el-checkbox class="w100" :label="v.name" :disabled="v.size === 0 && v.key.endsWith('/')"/>
											</div>
										</div>
									</div>
								</div>
							</div>
						</el-checkbox-group>
					</el-col>
				</el-row>
			</div>
			
			<el-empty v-else description="暂无数据"></el-empty>
			<template v-if="tableData.data.length > 0">
				<el-pagination
					@size-change="onPageSizeChange"
					@current-change="onPageCurrentChange"
					class="mt15"
					:hide-on-single-page="true"
					:pager-count="5"
					:page-sizes="[12, 24, 48, 96, 120, 240]"
					v-model:current-page="search.pageNum"
					v-model:page-size="search.pageSize"
					layout="total, sizes, prev, pager, next, jumper"
					:total="tableData.total"
				>
				</el-pagination>
			</template>
		</el-card>
		<CropperDialog ref="cropperDialogRef" :model="cropper.options" @submit="onCropperDialogSubmit" @cancel="onCropperDialogCancel"/>
	</div>
</template>

<script lang="ts">
import { ref, toRefs, reactive, onMounted, defineComponent } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { Session } from '/@/utils/storage';
import { copyText } from '/@/utils/commonFunction';
import CropperDialog from '/@/views/cms/material/cropper/index.vue';
import { getSiteConfig } from '/@/api/cms/channel/index';
import { getMaterialList, delMaterial, uploadPicture } from '/@/api/cms/helper/index';

export default defineComponent({
	name: 'cms/material',
	components: { CropperDialog },
	props: {
		// 绑定值
		model: {
			type: Object,
			default: () => {},
		}
	},
	setup(props) {
		const tableMaterialRef = ref();
		const uploadMaterialRef = ref();
		const cropperDialogRef = ref();
		const state = reactive({
			search: {
				folder: '',
				name: undefined,
				pageNum: 1,
				pageSize: 12,
			},
			tableData: {
				breads: [],
				previews: [],
				selections: [],//选中的行数据
				data: [],
				total: 0,
			},
			cropper: {
				options: {
					aspectRatio: 0,
				}
			},
			siteconfig: {},
			upload: {
				action: uploadPicture(),
				accept: '.svg,.webp,.gif,.jpg,.png,.jpeg,.bmp,.wbmp,.ico',
				headers: { Authorization: 'Bearer ' + Session.get('token') },
				name: 'upload',
				images: [],
				dialogVisible : false
			},
			images: ['bmp','gif','jpg','jpeg','png','ico','webp','svg','wbmp'],
			icons: [
				'apk',
				'bt',
				'code',
				'dir','doc','docx',
				'exe',
				'file','flash',
				'htm',
				'img',
				'mp3','mp4',
				'pdf','ppt','pptx','psd',
				'ttf','txt',
				'wps',
				'xls','xlsx',
				'zip',
			]
		});
		
		const loadSiteConfig = async (siteId: string) => {
			await getSiteConfig({'siteId': siteId}).then((res) => {
				if(res.code == 0 && res.data){
					state.siteconfig = res.data;
					state.search.folder = state.siteconfig?.siteCode + '/image';
					state.tableData.breads = [ state.siteconfig?.siteCode, 'image' ];
					state.upload.action = uploadPicture() + '&sitecode=' + state.siteconfig?.siteCode;
				}
			});
		}
		
		// 获取对象
		const loadTableData = async (params?: object) => {
			await getMaterialList(Object.assign(state.search, params)).then((res: any) => {
				if(res.code === 0){
					state.tableData = {
						total: res.total,
						data: res.data,
						breads: state.search.folder.split('/').filter(key => key),
						selections: [],
						previews: [],
					}
					res.data.forEach((v: any) => {
						if(v.size > 0 && state.images.includes(v.suffix)){
							state.tableData.previews.push(v.url);
						}
					});
				}
			});
		}
		//查询
		const onTableSearch = () => {
			loadTableData(state.search);
		}
		//重置
		const onResetSearch = () => {
			state.search.folder = state.siteconfig?.siteCode + '/image';
			state.search.name = undefined;
			state.search.pageNum = 1;
			state.search.pageSize = 12;
			loadTableData(state.search);
		}
		// 导航文件目录
		const onTreadcrumbClick = (key?: string) => {
			let folder = '';
			if(key){
				for(let i = 0; i < state.tableData.breads.length; i++){
					let item = state.tableData.breads[i];
					folder += '/' + item;
					if(item === key){
						break;
					}
				}
			}
			loadTableData({'folder': folder});
		}
		// 当前列表项点击
		const onTableItemClick = (v: any) => {
			if(v.size === 0 && v.key.endsWith('/')){
				loadTableData({folder: v.key});
			}
		};
		// 每页显示数据大小改变
		const onPageSizeChange = (val: number) => {
			state.search.pageSize = val;
			loadTableData(state.search);
		};
		// 页码改变
		const onPageCurrentChange = (val: number) => {
			state.search.pageNum = val;
			loadTableData(state.search);
		};
		// 删除选中行
		const onTabelRowsDel = () => {
			const keys: any = [];
			state.tableData.selections.forEach(name => {
				keys.push(state.search.folder + name);
			});
			if(keys && keys.length > 0){
				ElMessageBox.confirm('确定删除选中的文件信息吗？', '提示', {
					confirmButtonText: '删除',
					cancelButtonText: '取消',
					type: 'warning',
				}).then(() => {
					delMaterial(keys).then((res: any) => {
						if(res.code === 0){
							ElMessage.success('删除成功');
							loadTableData();
						}
					});
				}).catch(() => {});
			}
		};
		const onOpenCopyUrl = (row: object) => {
			copyText(row.url);
		}
		//上传之前
		const handleBeforeUpload = (file) => {
			state.upload.headers.Authorization = 'Bearer ' + Session.get('token');
		}
		//文件状态改变时
		const handleUploadChange = (file) => {
			if(file.status == 'ready') {
				const ext = file.name.substring(file.name.lastIndexOf('.'));
				if(file.size > 0 && state.upload.accept.indexOf(ext) != -1){
					cropperDialogRef.value.openDialog(file);
				}else{
					ElMessage.warning('请选择' + state.upload.accept + '格式的图片');
					state.upload.images = [];
				}
			}
		}
		const handleUploadExceed = () => {
			
		}
		//上传中
		const handleUploadPreview = (file) => {
			if(file.url){
				state.upload.dialogVisible = true;
			}
		};
		//上传成功
		const handleUploadSuccess = (res, file) => {
			if(res.state == 'SUCCESS' && res.url){
				onTableSearch();
				ElMessage.success('上传成功');
			}else if(res.state != 'SUCCESS'){
				ElMessage.success('上传失败');
			}
		};
		//移除
		const handleUploadRemove = (file) => {
			
		};
		const onCropperDialogSubmit = (file, base64) => {
			const newFile = base64ToFile(base64, file.name);
			uploadMaterialRef.value.handleRemove(file);
			uploadMaterialRef.value.handleStart(newFile);
			uploadMaterialRef.value.submit();
		}
		const onCropperDialogCancel = (file) => {
			uploadMaterialRef.value.handleRemove(file);
			uploadMaterialRef.value.clearFiles(['ready', 'uploading', 'success', 'fail']);
		}
		//将base64转换为文件
		const base64ToFile = (base64, filename) => { 
			var arr = base64.split(','),
			mime = arr[0].match(/:(.*?);/)[1],
			bstr = atob(arr[1]),
			n = bstr.length,
			u8arr = new Uint8Array(n);
			while (n--) {
				u8arr[n] = bstr.charCodeAt(n);
			}
			return new File([u8arr], filename, {type: mime});
		}
		// 页面加载时
		onMounted(async () => {
			await loadSiteConfig(props.model.siteId);
			await loadTableData();
		});
		return {
			tableMaterialRef,
			uploadMaterialRef,
			cropperDialogRef,
			onTableSearch,
			onResetSearch,
			onTabelRowsDel,
			onTreadcrumbClick,
			onTableItemClick,
			onPageSizeChange,
			onPageCurrentChange,
			onOpenCopyUrl,
			handleBeforeUpload,
			handleUploadChange,
			handleUploadExceed,
			handleUploadPreview,
			handleUploadSuccess,
			handleUploadRemove,
			onCropperDialogSubmit,
			onCropperDialogCancel,
			...toRefs(state),
		};
	},
});
</script>

<style scoped lang="scss">
.cms-material-container{	
	.flex-warp {
		display: flex;
		flex-wrap: wrap;
		align-content: flex-start;
		margin: 0 -5px;
		.flex-warp-item {
			padding: 0 5px;
			width: 100%;
			height: 200px;
			.flex-warp-item-box {
				border: 1px solid var(--el-color-primary-light-9);
				width: 100%;
				height: 100%;
				border-radius: 2px;
				display: flex;
				flex-direction: column;
				transition: all 0.3s ease;
				&:hover {
					cursor: pointer;
					border: 1px solid var(--el-color-primary-light-6);
					transition: all 0.3s ease;
					box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.03);
					.item-txt-title {
						color: var(--el-color-primary) !important;
						transition: all 0.3s ease;
						text-decoration: none;
					}
					.item-img {
						img {
							transition: all 0.3s ease;
							transform: translateZ(0) scale(1.05);
						}
					}
				}
				.item-img {
					width: 100%;
					display: flex;
					align-items: center;
					justify-content: center;
					height: 175px;
					overflow: hidden;
					img {
						transition: all 0.3s ease;
						width: 100%;
						height: 100%;
					}
				}
				.item-copy{
					position: absolute;
				}
				.item-txt {
					flex: 1;
					padding: 0 5px;
					display: flex;
					flex-direction: column;
					.item-txt-title {
						text-overflow: ellipsis;
						overflow: hidden;
						-webkit-line-clamp: 2;
						-webkit-box-orient: vertical;
						display: -webkit-box;
						color: var(--el-text-color-primary);
						transition: all 0.3s ease;
						&:hover {
							color: var(--el-color-primary);
							text-decoration: none;
							transition: all 0.3s ease;
						}
						.el-checkbox {
							height: 24px;
						}
					}
					.item-txt-other {
						flex: 1;
						align-items: flex-end;
						display: flex;
						.item-txt-msg {
							font-size: 12px;
							color: var(--el-text-color-primary);
						}
					}
				}
			}
		}
	}
	:deep .el-upload-list {
		display: none;
	}
}
</style>
